#pragma once

#include <algorithm>
#include <numeric>
#include <vector>
#include <set>

class WeirdPrimeGen
{
public:
    static long long countOnes( long long n );
    static long long maxPn( long long n );
    static int anOverAverage( long long n ) {
        return 3;
    }

    static std::vector<long long> anOver( long long n );

    static void moar( std::vector<long long> & a, std::vector<long long> & p );
};

void WeirdPrimeGen::moar( std::vector<long long> & a, std::vector<long long> & p ) {
    a.push_back( a.back() + std::gcd( a.back(), a.size() + 1 ) );
    p.push_back( a.back() - a.at( a.size() - 2 ) );
}

long long WeirdPrimeGen::countOnes( long long n )
{
    std::vector<long long> a{7};
    std::vector<long long> g{1};

    while( a.size() < n ) {
        moar( a, g );
    }

    return std::count( g.begin(), g.end(), 1 );
}

long long WeirdPrimeGen::maxPn( long long n )
{
    std::vector<long long> a{7};
    std::vector<long long> g{1};
    std::set<long long> result;
    result.insert( 1 );

    while( result.size() < n + 1 ) {
        moar( a, g );
        result.insert( g.back() );
    }

    return *result.rbegin();
}

std::vector<long long> WeirdPrimeGen::anOver( long long n )
{
    std::vector<long long> a{7};
    std::vector<long long> g{1};
    std::vector<long long> result;

    while( result.size() < n ) {
        moar( a, g );

        if( g.back() != 1 ) {
            result.push_back( a.back() / a.size() );
        }
    }

    return result;
}

